【并发】threading & multiprocessing

参考:

结论:

  • 由于python是一个解释性语言,即在执行时需要CPython编译器(或JPython等),其在为引入全局变量时,构建了GIL(全局锁)。导致python在进行多线程时,由于GIL的存在,本该异步进行的任务,会抢夺一个线程上的全局锁,导致依然一个线程上执行
  • 即对I/O密集型任务,采用多线程ok,否则多线程反而起反作用
  • python使用多进程可以有效的利用多核CPU

实现

# 进程池实现
from muiltprocessing import Pool
import time

def add(num):
    res = 1
    for i in range(num):
        res += i
    print('mut:', time.time.now())
    return res

def mut(num):
    res = 1
    for i in range(num):
        res *= i
    print('mut:', time.time.now())
    return res

pool = Pool(4)   # 创建包含4个进程的进程池
pool.apply_async(func=add, 100000)    # 添加进程
pool.apply_async(func=mut, 100000)   # 添加进程
p.close()       # 等任务结束后关闭进程池
# p.terminate()     # 立刻关闭进程池
p.join()        # 主进程等待所有子进程执行完毕

# 进程添加实现
from muiltprocessing import Process

t1 = Process(task=add, 10000)
t2 = Process(task=mut, 10000)     # 创建process对象
t1.start()
t2.start()                        # 调用process对象生成进程
t1.join()
t2.join()                         # 等待进程执行完毕,可以通过设置timeout确定任务阻塞时间

# 进程间的通讯通道 -- 队列
## 实质:合理安排不同任务对应的执行进程,目的是保证线程、进程安全
from muiltprocessing import Queue
q = Queue()                       # 创建任务队列
t1 = Process(task=add, 10000)
t2 = Process(task=mut, 10000)     # 创建process对象
t1.start()
t2.start()                        # 生成进程
print(q.get())                    # 获取任务队列的生成结果
t1.join()
t2.join()

# 进程的通讯通道 -- 管道
## 实质

说明:

  1. 进程池pool无法放在类内进行同步调用,原因是实例方法不能被pickle
  2. 进程池只能由创建的进程使用,且在交互解释器内不能使用

results matching ""

    No results matching ""